package cn.codeforfun.gitee.utils;

import cn.codeforfun.gitee.api.exception.GiteeResponseException;
import okhttp3.*;
import org.springframework.http.HttpStatus;

import java.io.IOException;
import java.util.Map;

/**
 * OkHttp工具类
 *
 * @author wangbin
 */
public class OkHttpUtils {

    public static final int HTTP_RESPONSE_OK = 200;

    public static String get(String url) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder().build();

        Request request = new Request.Builder()
                .url(url)
                .method("GET", null)
                .build();
        return getResponse(client, request);
    }

    public static String get(String url, Object parameterBean) throws IOException {
        Map<String, Object> parameter = JsonUtils.toMap(JsonUtils.toJson(parameterBean));
        return get(url, parameter);
    }


    public static String get(String url, Map<String, Object> parameter) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder().build();

        HttpUrl.Builder builder = getUrlBuilder(url, parameter);
        Request request = new Request.Builder().url(builder.build()).method("GET", null).build();
        return getResponse(client, request);
    }

    public static String delete(String url, Object parameter) throws IOException {
        return delete(url, JsonUtils.toMap(JsonUtils.toJson(parameter)));
    }

    public static String delete(String url, Map<String, Object> parameter) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();

        HttpUrl.Builder builder = getUrlBuilder(url, parameter);
        Request request = new Request.Builder().url(builder.build()).method("DELETE", null).build();
        return getResponse(client, request);
    }

    public static String post(String url, Map<String, Object> bodyMap) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder().build();

        String type = "application/json";
        MediaType mediaType = MediaType.parse(type);
        RequestBody body = RequestBody.create(mediaType, JsonUtils.toJson(bodyMap));
        Request request = new Request.Builder()
                .url(url)
                .method("POST", body)
                .addHeader("Content-Type", type)
                .build();
        return getResponse(client, request);
    }

    public static String postUrlEncoder(String url, Map<String, Object> bodyMap) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        String type = "application/x-www-form-urlencoded";
        MediaType mediaType = MediaType.parse(type);

        StringBuilder content = new StringBuilder();
        for (Map.Entry<String, Object> entry : bodyMap.entrySet()) {
            content.append("&").append(entry.getKey()).append("=").append(entry.getValue());
        }
        content = new StringBuilder(content.substring(1));
        RequestBody body = RequestBody.create(mediaType, content.toString());
        Request request = new Request.Builder()
                .url(url)
                .method("POST", body)
                .addHeader("Content-Type", type)
                .build();
        return getResponse(client, request);
    }

    public static String postForm(String url, Object body) throws IOException {
        return postForm(url, JsonUtils.toMap(JsonUtils.toJson(body)));
    }

    public static String putForm(String url, Object body) throws IOException {
        return putForm(url, JsonUtils.toMap(JsonUtils.toJson(body)));
    }

    public static String postForm(String url, Map<String, Object> bodyMap) throws IOException {
        return formRequest(url, bodyMap, "POST");
    }

    public static String putForm(String url, Map<String, Object> bodyMap) throws IOException {
        return formRequest(url, bodyMap, "PUT");
    }

    public static String formRequest(String url, Map<String, Object> bodyMap, String methodType) throws IOException {

        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        for (Map.Entry<String, Object> entry : bodyMap.entrySet()) {
            if (null != entry.getValue()) {
                builder.addFormDataPart(entry.getKey(), String.valueOf(entry.getValue()));
            }
        }
        RequestBody body = builder.build();
        Request request = new Request.Builder()
                .url(url)
                .method(methodType, body)
                .build();
        return getResponse(client, request);
    }

    private static String getResponse(OkHttpClient client, Request request) throws IOException {
        Response response = client.newCall(request).execute();
        if (HttpStatus.OK.value() == response.code() || HttpStatus.CREATED.value() == response.code()) {
            return response.body() == null ? null : response.body().string();
        } else if (HttpStatus.NO_CONTENT.value() == response.code()) {
            return null;
        } else if (HTTP_RESPONSE_OK != response.code()) {
            throw new GiteeResponseException(response.body() == null ? null : response.body().string());
        }
        return null;
    }

    private static HttpUrl.Builder getUrlBuilder(String url, Map<String, Object> parameter) {
        HttpUrl parse = HttpUrl.parse(url);
        assert parse != null;
        HttpUrl.Builder builder = parse.newBuilder();
        for (Map.Entry<String, Object> entry : parameter.entrySet()) {
            if (null != entry.getValue()) {
                builder.addQueryParameter(entry.getKey(), String.valueOf(entry.getValue()));
            }
        }
        return builder;
    }

}
